package com.yanqu.road.dao.db;

import com.yanqu.road.utils.LogUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.sql.*;
import java.util.List;
import java.util.Map;

public class DbPoolMgr {

    private static Logger log = LogManager.getLogger(DbPoolMgr.class.getName());

    private static DbPoolMgr instance = new DbPoolMgr();

    private DbPool dbPool;

    private DbPoolMgr() {
    }

    public static DbPoolMgr getInstance() {
        return instance;
    }

    public void createPool(DbPool dbPool) {
        this.dbPool = dbPool;
    }

    public Connection getConn() {
        try {
            return dbPool.getConnection();
        } catch (SQLException e) {
            LogUtils.ERROR.error("getConn error", e);
        }
        return null;
    }

    public DbPool getDbPool() {
        return dbPool;
    }

    /**
     * 批处理操作
     *
     * @param sqlText
     * @param params
     * @return
     */
    public int executeBatchQuery(Connection conn, String sqlText, List<Map<Integer, DbParameter>> params) {
        if (params == null || conn == null)
            return -1;
        int count = 0;
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(sqlText, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
            for (Map<Integer, DbParameter> map : params) {
                prepareCommand(ps, map);
                ps.addBatch();
                count++;
            }
            ps.executeBatch();
            ps.clearBatch();
            ps.close();
            return 1;
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        } finally {
            try {
                if (ps != null && !ps.isClosed()) {
                    ps.close();
                }
            } catch (Exception ex) {
                log.error(ex.getMessage(), ex);
            }
        }
        return -1;
    }

    public int executeNoneQuery(String sqlText, Map<Integer, DbParameter> params) {
        Connection conn = DbPoolMgr.getInstance().getConn();
        PreparedStatement pstmt = null;
        try {
            pstmt = conn.prepareStatement(sqlText);
            prepareCommand(pstmt, params);

            return pstmt.executeUpdate();
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        } finally {
            closeConnection(conn, pstmt);

        }
        return -1;

    }

    private void prepareCommand(PreparedStatement pstmt, Map<Integer, DbParameter> parms) throws SQLException {
        if (parms == null)
            return;
        for (Map.Entry<Integer, DbParameter> entry : parms.entrySet()) {
            pstmt.setObject(entry.getKey(), entry.getValue().getResult());
        }
    }

    public void closeConnection(Connection conn, Statement ps) {
        try {
            if (ps != null && !ps.isClosed()) {
                ps.close();
            }
            if (conn != null && !conn.isClosed()) {
                conn.close();
            }
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        }
    }
}
